#version 400

uniform sampler2D texture;
uniform sampler2D terrainTexture;
uniform sampler2D rockTexture;

uniform float textureStep;
uniform float terrainMultiplier;
uniform float rockMultiplier;
uniform float mapMultiplier;
uniform float mapBase;
uniform float terrainStickPower;

uniform vec3 lightIntensity;
uniform vec3 lightPosition;
uniform vec2 lightMode;

uniform mat3 normalMatrix;

in VertexData {
    vec3 vert;
    vec3 coords;
    vec2 texCoord;
    vec4 shadowCoord;
    float zPos;
} vertex;

layout( location = 0 ) out vec4 fragColor;

vec3 calculateNormal(float mul)
{
    vec2 tc = vertex.texCoord;
    vec3 n0 = vertex.coords;

    vec3 n1 = vec3(n0.x - textureStep,
                   mapBase + (texture(terrainTexture,tc - vec2(textureStep,0.0)).y) * mul,
                   n0.z);
    vec3 n2 = vec3(n0.x,
                   mapBase + (texture(terrainTexture,tc + vec2(0.0,textureStep)).y) * mul,
                   n0.z + textureStep);

    vec3 n3 = vec3(n0.x + textureStep,
                   mapBase + (texture(terrainTexture,tc + vec2(textureStep,0.0)).y) * mul,
                   n0.z);
    vec3 n4 = vec3(n0.x,
                   mapBase + (texture(terrainTexture,tc - vec2(0.0,textureStep)).y) * mul,
                   n0.z - textureStep);

    vec3  normal = normalize(cross(n1-n0,n2-n0) + cross(n3-n0,n4-n0)
                             + cross(n4-n0,n1-n0) + cross(n2-n0,n3-n0));
    return normal;
}

void main()
{
    if(lightMode.x == 1.0) {
        fragColor = vec4(0.0,0.0,0.0,1.0);
    } else {
        float mul = 1.0;
        if(mapMultiplier == 0.0)
            mul = 0.0;
        vec3 normal = calculateNormal(mul);
        float colorNormal = abs(normalize(vec3(normal.x,normal.y * terrainStickPower,normal.z))).y;
        normal = normalize(normalMatrix * normal.xyz);

        vec4 textureColor = texture2D(texture,vertex.texCoord * terrainMultiplier);
        vec4 rockTextureColor = texture2D(rockTexture,vertex.texCoord * rockMultiplier);

        textureColor = (rockTextureColor * (1.0 - colorNormal)) + textureColor * colorNormal;

        vec3 lightDir = normalize(lightPosition - vertex.coords);
        vec3 nightLightDir = normalize(vertex.coords - lightPosition);

        vec3 diffuse = vec3(2.0 - (1.0 - dot(lightDir,normal))) * 0.75;

        vec4 diffuesColor = textureColor * vec4(lightIntensity * diffuse,1.0 ).x;

        vec4 ambientColor = textureColor * 0.5;
        fragColor =  diffuesColor + ambientColor;
        fragColor.a = 1.0;
    }
}
